package com.phpxiu.app.avlive;

import android.content.Context;
import android.text.Editable;
import android.text.TextUtils;

import com.phpxiu.app.controller.avcontroller.QavsdkControl;
import com.phpxiu.app.model.MySelfInfo;
import com.tencent.TIMCallBack;
import com.tencent.TIMConversation;
import com.tencent.TIMConversationType;
import com.tencent.TIMCustomElem;
import com.tencent.TIMManager;
import com.tencent.TIMMessage;
import com.tencent.TIMMessageListener;
import com.tencent.TIMTextElem;
import com.tencent.TIMUser;
import com.tencent.TIMValueCallBack;

import java.util.List;
import java.util.Observable;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @file
 * @brief 通讯管理--被观察者
 * @author 吴金洲
 * @note 1.会话管理。2.消息接收、分发处理.
 *
 */
public class MsgManager extends Observable implements TIMMessageListener,TIMCallBack {
    /**
     * 腾讯云互动直播应用ID,从腾讯云互动直播控制台创建互动直播应用后获取
     */
    private final static int SDK_APP_ID=1400010661;
    /**
     * 互动直播用户云资料关系模式(酷酷鱼直播为独立模式)，从腾讯云互动直播控制台创建互动直播应用后获取。
     */
    private final static int ACCOUNT_TYPE=5570;

    /**
     * 应用程序内容
     */
    private Context mContext;

    /**
     * 是否初始化
     */
    private boolean isInit=false;

    /**
     * 通讯管理实例
     */
    private volatile static MsgManager manager;

    /**
     * 腾讯即时通讯管理实例
     */
    private TIMManager timManager;

    /**
     * 私信会话列表
     */
    private ConcurrentHashMap<String,TIMConversation> conversations=new ConcurrentHashMap<String,TIMConversation>();

    /**
     * 群会话
     */
    /**
     * 私信会话列表
     */
    private ConcurrentHashMap<String,TIMConversation> groups=new ConcurrentHashMap<String,TIMConversation>();

    /**
     * 获取直播管理单例
     * @return
     */
    public static MsgManager getInstance(){
        if (manager == null) {
            synchronized (MsgManager.class) {
                if (manager == null) {
                    manager = new MsgManager();
                }
            }
        }
        return manager;
    }

    /**
     * 初始化
     * @param context 应用程序
     */
    public void init(Context context){
        mContext=context;
        TIMManager.getInstance().init(context);
        isInit=true;
    }

    /**
     * 登录IM
     * @param identify 用户id：由业务后台维护与互动直播服务中的资料一致。
     * @param userSig IM服务登录签名：用户请求业务后台登录成功后，业务服务器调用互动直播接口生成后返回.
     */
    public static void IMLogin(String identify,String userSig){
        TIMUser user = new TIMUser();
        user.setAppIdAt3rd(String.valueOf(SDK_APP_ID));
        user.setAccountType(String.valueOf(ACCOUNT_TYPE));
        user.setIdentifier(identify);
        //向互动直播服务请求登录IM
        TIMManager.getInstance().login(SDK_APP_ID,user, userSig,getInstance());
    }

    /**
     * IM登录失败回调
     * @param code
     * @param msg
     */
    @Override
    public void onError(int code, String msg) {

    }

    /**
     * IM登录成功回调
     */
    @Override
    public void onSuccess() {
        //启动音视频SDK
        startAVSDK();
    }



    /**
     * 获取私信会话
     * @param g 群组会话id
     * @return 群组会话
     */
    private TIMConversation findGroup(String g){
        if(!groups.containsKey(g)){//没有找到会话,创建一个
            return null;
        }
        return groups.get(g);
    }

    private void removeGroup(String group){
        if(groups.containsKey(group)){
            groups.remove(group);
        }
    }

    /**
     * 判断群组是否存在
     * @return
     */
    private static boolean groupExist(String g){
        if(TextUtils.isEmpty(g)||getInstance().findGroup(g)==null){
            return true;
        }
        return false;
    }

    /**
     * @brief 高优先级群消息
     * @note 通知、红包级别的消息,丢弃率最低
     */
    public static void sendGroupMsg(String json,SEND SEND,String id,TIMValueCallBack<TIMMessage>callBack){
        if(groupExist(id)){
            TIMMessage message=new TIMMessage();
            TIMCustomElem elem=new TIMCustomElem();
            elem.setData(json.getBytes());
            elem.setDesc("");
            message.addElement(elem);
            switch (SEND){
                case HIGH:
                    getInstance().findGroup(id).sendRedPacketMessage(message,callBack);
                    break;
                case MID:
                    getInstance().findGroup(id).sendMessage(message,callBack);
                    break;
                case LOW:
                    getInstance().findGroup(id).sendLikeMessage(message,callBack);
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * @brief 无优先级别群消息
     * @note 普通文本聊天群消息，高峰发送期，可能会被丢弃。
     */
    public static void sendTextMsg(String msg,String id,TIMValueCallBack<TIMMessage>callBack){
        if(groupExist(id)){
            TIMMessage message=new TIMMessage();
            TIMTextElem elem=new TIMTextElem();
            elem.setText(msg);
            message.addElement(elem);
            getInstance().findGroup(id).sendMessage(message,callBack);
        }
    }

    /**
     * 获取私信会话
     * @param peer
     * @return
     */
    private TIMConversation findConversation(String peer){
        if(!conversations.containsKey(peer)){//没有找到会话,创建一个
            conversations.put(peer,TIMManager.getInstance().getConversation(TIMConversationType.C2C,peer));
        }
        return conversations.get(peer);
    }

    /**
     * 发送私信
     * @param msgContent 文本内容
     * @param receiver 接收者
     */
    public static void sendMsg(Editable msgContent,String receiver,TIMValueCallBack<TIMMessage> callBack){
        TIMMessage message=new TIMMessage();
        TIMTextElem textElem = new TIMTextElem();
        textElem.setText(msgContent.subSequence(0, msgContent.length()).toString());
        message.addElement(textElem);
        getInstance().findConversation(receiver).sendMessage(message,callBack);
    }

    /**
     * 发送私信
     * @param msg jason格式的消息
     * @param receiver 接收者
     */
    public static void sendMsg(String msg,String receiver,boolean isOnline,TIMValueCallBack<TIMMessage> callBack){
        TIMMessage message=new TIMMessage();
        TIMCustomElem elem=new TIMCustomElem();
        elem.setData(msg.getBytes());
        elem.setDesc("");
        message.addElement(elem);
        if(isOnline){
            getInstance().findConversation(receiver).sendOnlineMessage(message,callBack);
        }else{
            getInstance().findConversation(receiver).sendMessage(message,callBack);
        }
    }


    /**
     * @brief IM消息监听回调
     * @param timMessages IM消息列表
     * @return true：IM收到消息时，会调用此方法，添加的其它监听回调方法不会再被调用。
     * @note IM实例可以设置多个监听，如果此方法返回true，则不会调用之后的监听了。
     */
    @Override
    public boolean onNewMessages(List<TIMMessage> timMessages) {
        return false;
    }

    /**
     * 启动音视频SDK
     * @return
     * @see com.phpxiu.app.config.Constants#DEMO_ERROR_NULL_POINTER,
     * @see com.tencent.av.sdk.AVError#AV_ERR_FAILED
     * @see com.tencent.av.sdk.AVError#AV_OK
     */
    final private static int startAVSDK() {
        QavsdkControl.getInstance().setAvConfig(SDK_APP_ID,String.valueOf(ACCOUNT_TYPE), MySelfInfo.getInstance().getId(),MySelfInfo.getInstance().getUserSig());
        return QavsdkControl.getInstance().startContext();
    }


    /**
     * 通知观察者，更新数据
     * @param data
     */
    public void onCommunicationChange(Object data){
        setChanged();
        notifyObservers(data);
    }

    /**
     * 消息发送优先级别
     */
    enum SEND{
        HIGH,MID,LOW;
    }
}
